package sipus.action.maintenance;

import java.io.File;
import java.net.InetAddress;
import java.util.Date;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Sessions;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.sys.ExecutionsCtrl;
import org.zkoss.zk.ui.util.GenericAutowireComposer;
import org.zkoss.zul.A;
import org.zkoss.zul.Filedownload;
import org.zkoss.zul.Image;
import org.zkoss.zul.Messagebox;
import org.zkoss.zul.Tabbox;
import org.zkoss.zul.Toolbarbutton;
import org.zkoss.zul.Tree;
import org.zkoss.zul.Treechildren;
import org.zkoss.zul.Treeitem;
import org.zkoss.zul.Window;

import sipus.action.master.helper.ChangePasswordWindow;
import sipus.action.master.helper.DaftarPenggunaOnline;
import sipus.common.Common;
import sipus.common.CommonPrivilages;
import sipus.database.hibernate.HibernateUtil;
import sipus.database.model.AccessedUsers;
import sipus.database.model.DetailLogLogin;
import sipus.database.model.LogLogin;
import sipus.database.model.Menu;
import sipus.database.model.OnlineUsers;
import sipus.database.model.Tbmrole;
import sipus.database.model.Tbmuser;


public class MainAction extends GenericAutowireComposer {

	/**
	 * 
	 */
	private static final long serialVersionUID = 2446397351568124278L;
	private Tabbox iframe;
	private Tree menubar;
	private Image header;
	private A footer;

	private Toolbarbutton usersOnline;
	private Tbmuser tbmuser;
	private LogLogin login;

	public void doAfterCompose(Component comp) throws Exception {
		// TODO Auto-generated method stub
		super.doAfterCompose(comp);

		// Clients.confirmClose("Harap selalu logout sebelum keluar aplikasi.");

		Common.setting(header, footer, null, null);

		tbmuser = Common
				.getCurrentFromSpringUser((HttpServletRequest) execution
						.getNativeRequest());
		login = (LogLogin) session.getAttribute("login");
		session.setAttribute("usersTemp", tbmuser);

		System.out.println("session.getAttribute(\"usersTemp\") = "
				+ session.getAttribute("usersTemp"));
		if (session.getAttribute("usersTemp") == null) {
			session.removeAttribute("usersTemp");
			execution.sendRedirect("/logoff");
			return;
		}

		loadTree();

		onUpdateUserOnline(null);

		// changePassword.setVisible(false);
	}

	public void onLihatOnline(Event event) throws Exception {
		DaftarPenggunaOnline window = new DaftarPenggunaOnline(
				(HttpServletRequest) ExecutionsCtrl.getCurrent()
						.getNativeRequest());
		ExecutionsCtrl.getCurrentCtrl().getCurrentPage().getFirstRoot()
				.appendChild(window);
		window.setVisible(true);
		window.onModal();
	}

	public void onUpdateUserOnline(Event e) {
		try {
			if (session.getAttribute("usersTemp") == null) {
				session.removeAttribute("usersTemp");
				execution.sendRedirect("/logoff");
				return;
			}
			HttpServletRequest request = (HttpServletRequest) ExecutionsCtrl
					.getCurrent().getNativeRequest();
			String req = request.getRequestURL().toString();
			req = req.replaceAll("http://", "");
			req = req.split(":")[0];
			req = req.split("/")[0];
			Session session = HibernateUtil.currentSession();
			Number count = (Number) session.createCriteria(AccessedUsers.class)
					.add(Restrictions.eq("host", req))
					.setProjection(Projections.count("id")).uniqueResult();

			Number countOnline = (Number) session
					.createCriteria(OnlineUsers.class)
					.add(Restrictions.eq("host", req))
					.setProjection(Projections.count("id")).uniqueResult();

			InetAddress addr = InetAddress.getLocalHost();
			String hostname = addr.getHostName();
			String result = "User(s) access: " + count + ", logged in: "
					+ countOnline + " (" + hostname + ")";
			// System.out.println("result = " + result);
			usersOnline.setLabel(result);
		} catch (Exception e1) {
			e1.printStackTrace();
		}
	}

	private synchronized Boolean hasChild(Integer root, Set<Menu> menus) {
		for (Menu menu : menus) {
			if (menu.getRoot().equals(root)) {
				return true;
			}
		}
		return false;
	}

	private void createRootSubMenu(final Tabbox iframe, Integer root,
			Set<Menu> menus, Treeitem parenttreeitem) {
		Treechildren tc1 = new Treechildren();
		tc1.setParent(parenttreeitem);
		for (final Menu menu : menus) {
			if (menu.getRoot().equals(root)) {
				Boolean ada = hasChild(menu.getChild(), menus);
				if (ada) {
					Treeitem treeitem = new Treeitem(menu.getLabel(),
							menu.getUrl());
					treeitem.setOpen(false);
					treeitem.setParent(tc1);
					if (menu.getIcon() != null
							&& !menu.getIcon().trim().equals("")) {
						treeitem.setImage(menu.getIcon().trim());
					} else {
						treeitem.setImage("/img/dir.gif");
					}
					createRootSubMenu(iframe, menu.getChild(), menus, treeitem);
				} else {
					Treeitem treeitem = new Treeitem(menu.getLabel(),
							menu.getUrl());
					if (menu.getIcon() != null
							&& !menu.getIcon().trim().equals("")) {
						treeitem.setImage(menu.getIcon().trim());
					} else {
						treeitem.setImage("/img/doc.png");
					}
					treeitem.setOpen(false);
					treeitem.setParent(tc1);
					treeitem.addEventListener("onClick", new EventListener() {
						@SuppressWarnings({})
						public void onEvent(Event event) throws Exception {

							Sessions.getCurrent().setAttribute("currentMenu",
									menu);

							if (!CommonPrivilages
									.checkPrevilages(CommonPrivilages.READ)) {
								Messagebox
										.show("Maaf, anda tidak diperkenankan untuk mengakses menu ini",
												"Peringatan", Messagebox.OK,
												Messagebox.EXCLAMATION);
								return;
							}

							DetailLogLogin detailLogLogin = new DetailLogLogin();
							detailLogLogin.setKeterangan(menu.getLabel());
							detailLogLogin.setWaktu(new Date());
							detailLogLogin.setLogLogin(login);
							detailLogLogin.setHalaman(menu.getUrl());
							HibernateUtil.currentSession().save(detailLogLogin);
							Sessions.getCurrent().setAttribute(
									"detailLogLogin", detailLogLogin);

							if (tampilWindow(menu)) {
								return;
							}

							try {
								if (menu.getUrl().trim()
										.equals("rubah_password")) {
									ChangePasswordWindow window = new ChangePasswordWindow();
									window.setVisible(true);
									Common.insertToTab(iframe, menu, window,
											login);

								} else {
									Common.insertToTab(iframe, menu, login);
								}
							} catch (Exception e) {
								Messagebox
										.show("Maaf, menu ini masih dalam proses konstruksi",
												"Pemberitahuan", Messagebox.OK,
												Messagebox.EXCLAMATION);
								e.printStackTrace();
							}
						}
					});
				}
			}
		}

	}

	private boolean tampilWindow(Menu menu) {
		try {

			if (menu.getUrl().trim().startsWith("sipus.action.report.window")) {
				Window window = (Window) Class.forName(menu.getUrl().trim())
						.newInstance();
				Common.insertToTab(iframe, menu, window, login);
			} else {
				Window window = (Window) Class.forName(menu.getUrl().trim())
						.newInstance();
				ExecutionsCtrl.getCurrentCtrl().getCurrentPage().getFirstRoot()
						.appendChild(window);
				window.setTitle(menu.getLabel());
				window.setVisible(true);
				window.onModal();
			}
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	public synchronized Treechildren createTreeMenu(final Tabbox iframe,
			Tree menubar, Tbmrole job) {
		final Set<Menu> menus = job.getMenus();
		Treechildren tc1 = new Treechildren();
		tc1.setParent(menubar);
		for (final Menu menu : menus) {
			if (menu.getRoot().equals(0)) {

				Boolean ada = hasChild(menu.getChild(), menus);
				if (ada) {
					Treeitem treeitem = new Treeitem(menu.getLabel(),
							menu.getUrl());
					treeitem.setParent(tc1);
					treeitem.setOpen(false);
					if (menu.getIcon() != null
							&& !menu.getIcon().trim().equals("")) {
						treeitem.setImage(menu.getIcon().trim());
					} else {
						treeitem.setImage("/img/dir.gif");
					}
					createRootSubMenu(iframe, menu.getChild(), menus, treeitem);
				} else {
					Treeitem treeitem = new Treeitem(menu.getLabel(),
							menu.getUrl());
					treeitem.setParent(tc1);
					treeitem.setOpen(false);
					if (menu.getIcon() != null
							&& !menu.getIcon().trim().equals("")) {
						treeitem.setImage(menu.getIcon().trim());
					} else {
						treeitem.setImage("/img/doc.png");
					}
					treeitem.addEventListener("onClick", new EventListener() {
						public void onEvent(Event event) throws Exception {

							Sessions.getCurrent().setAttribute("currentMenu",
									menu);

							DetailLogLogin detailLogLogin = new DetailLogLogin();
							detailLogLogin.setKeterangan(menu.getLabel());
							detailLogLogin.setWaktu(new Date());
							detailLogLogin.setLogLogin(login);
							HibernateUtil.currentSession().save(detailLogLogin);
							Sessions.getCurrent().setAttribute(
									"detailLogLogin", detailLogLogin);

							if (tampilWindow(menu)) {
								return;
							}

							if (menu.getUrl() != null
									&& menu.getUrl().trim()
											.endsWith("login.zul")) {
								Messagebox.show("Keluar dari Aplikasi ?",
										"Question", Messagebox.OK
												| Messagebox.CANCEL,
										Messagebox.QUESTION,
										new EventListener() {

											@Override
											public void onEvent(Event event)
													throws Exception {
												int i = new Integer(event
														.getData().toString());
												if (i == Messagebox.CANCEL)
													return;
												session.removeAttribute("usersTemp");
												execution
														.sendRedirect("/logoff");

											}
										});
							} else {
								Common.insertToTab(iframe, menu, login);
							}
						}
					});
				}
			}
		}
		return tc1;
	}

	public synchronized void loadTree() {
		Tbmuser users = (Tbmuser) Sessions.getCurrent().getAttribute(
				"usersTemp");
		if (users == null || users.getUserRole() == null
				|| users.getUserRole().getMenus() == null)
			return;

		Session ses = HibernateUtil.currentSession();

		DetailLogLogin detailLogLogin = (DetailLogLogin) ses
				.createCriteria(DetailLogLogin.class)
				.add(Restrictions.eq("logLogin", login))
				.add(Restrictions.eq("keterangan", "Login")).setMaxResults(1)
				.uniqueResult();
		if (detailLogLogin == null) {
			detailLogLogin = new DetailLogLogin();
		}
		detailLogLogin.setKeterangan("Login");
		detailLogLogin.setWaktu(new Date());
		detailLogLogin.setLogLogin(login);
		ses.saveOrUpdate(detailLogLogin);

		Criteria criteria = ses.createCriteria(Tbmuser.class);
		criteria.add(Restrictions.idEq(users.getUserId()));
		users = ((Tbmuser) criteria.uniqueResult());
		Sessions.getCurrent().setAttribute("users", users);
		users = (Tbmuser) Sessions.getCurrent().getAttribute("users");
		Treechildren tc1;

		Tbmrole tbmrole = (Tbmrole) HibernateUtil.currentSession().load(
				Tbmrole.class, users.getUserRole().getRoleId());
		tc1 = createTreeMenu(iframe, menubar, tbmrole);

		Treeitem menuitem = new Treeitem("Bantuan", "bantuan");
		menuitem.setImage("/img/help.gif");
		menuitem.setOpen(false);
		menuitem.setParent(tc1);
		menuitem.addEventListener("onClick", new EventListener() {
			public void onEvent(Event event) throws Exception {

				DetailLogLogin detailLogLogin = new DetailLogLogin();
				detailLogLogin.setKeterangan("Bantuan");
				detailLogLogin.setWaktu(new Date());
				detailLogLogin.setLogLogin(login);
				HibernateUtil.currentSession().save(detailLogLogin);
				Sessions.getCurrent().setAttribute("detailLogLogin",
						detailLogLogin);

				HttpServletRequest request = (HttpServletRequest) ExecutionsCtrl
						.getCurrent().getNativeRequest();
				String req = request.getRequestURL().toString();
				req = req.replaceAll("http://", "");
				req = req.split(":")[0];
				req = req.split("/")[0];

				Filedownload.save(
						new File(
								application
										.getRealPath("/help/User_Manual__Sistem_Rumah_Sakit.pdf")),
						"application/pdf");

			}
		});

		menuitem = new Treeitem("Keluar Aplikasi", "../login.zul");
		menuitem.setImage("/img/shutdown.PNG");
		menuitem.setOpen(false);
		menuitem.setParent(tc1);
		menuitem.addEventListener("onClick", new EventListener() {
			public void onEvent(Event event) throws Exception {

				DetailLogLogin detailLogLogin = new DetailLogLogin();
				detailLogLogin.setKeterangan("Keluar Aplikasi");
				detailLogLogin.setWaktu(new Date());
				detailLogLogin.setLogLogin(login);
				HibernateUtil.currentSession().save(detailLogLogin);
				Sessions.getCurrent().setAttribute("detailLogLogin",
						detailLogLogin);

				Messagebox.show("Keluar dari Aplikasi ?", "Question",
						Messagebox.OK | Messagebox.CANCEL, Messagebox.QUESTION,
						new EventListener() {

							@Override
							public void onEvent(Event event) throws Exception {

								int i = new Integer(event.getData().toString());
								if (i == Messagebox.CANCEL)
									return;
								session.removeAttribute("usersTemp");
								execution.sendRedirect("/logoff");
							}
						});

			}
		});

	}

}
